import 'dart:io';
import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wu_you/res/strings.dart';
import 'package:wu_you/utils/logger_util.dart';
import 'package:wu_you/utils/login_util.dart';

abstract class HttpBloc<T> extends Bloc<HttpEvent, HttpState> {
  HttpBloc() : super(HttpLoading(null));

  @override
  Stream<HttpState> mapEventToState(HttpEvent event) async* {
    yield HttpLoading(event);
    HttpState state = await obtainData(event).then<HttpState>((value) {
      if (value == null) {
        return HttpSuccess(event);
      }
      if (value is List && value.isEmpty) {
        return HttpSuccess(event);
      }
      return HttpSuccessWithData(event, value);
    }).catchError((e) {
      if (e is DioError) {
        var response = e.response;
        if (response != null && response.statusCode == HttpStatus.unauthorized) {
          // LoginUtil.logout();
          return HttpFailure(event, e.error);
        }
        return HttpFailure(event, e.error.toString());
      }
      LoggerUtil.e(e);
      return HttpFailure(event, AppStrings.networkError);
    });
    yield state;
  }

  Future<T> obtainData(HttpEvent event);
}

class HttpEvent extends Equatable {
  @override
  List<Object> get props => [];
}

class IdHttpEvent extends HttpEvent {
  final int id;

  IdHttpEvent(this.id) : assert(id > 0);
  @override
  List<Object> get props => [id];
}
class IdStrHttpEvent extends HttpEvent {
  final String id;

  IdStrHttpEvent(this.id);
  @override
  List<Object> get props => [id];
}

class IdsHttpEvent extends HttpEvent {
  final int id;

  IdsHttpEvent(this.id);
  @override
  List<Object> get props => [id];
}

///分页
class PageSizeHttpEvent extends HttpEvent {
  final int page;
  final int size;
  PageSizeHttpEvent(this.page, this.size,)
      : assert(page > 0),
        assert(size > 0);

  @override
  List<Object> get props => [page, size];
}

///需要位置数据的请求事件
class LocationHttpEvent extends HttpEvent {
  final String latitude;
  final String longitude;

  LocationHttpEvent(this.latitude, this.longitude);

  @override
  List<Object> get props => [latitude, longitude];
}

///搜索事件
class SearchHttpEvent extends HttpEvent {
  final String content;

  SearchHttpEvent(this.content);

  @override
  List<Object> get props => [content];
}

@immutable
abstract class HttpState extends Equatable {
  final HttpEvent httpEvent;

  const HttpState(this.httpEvent);
}

///加载中
class HttpLoading extends HttpState {
  HttpLoading(HttpEvent httpEvent) : super(httpEvent);

  @override
  List<Object> get props => [];
}

///请求失败
class HttpFailure extends HttpState {
  final String msg;

  HttpFailure(HttpEvent httpEvent, this.msg) : super(httpEvent);

  @override
  List<Object> get props => [msg];
}

///请求成功但无数据
class HttpSuccess extends HttpState {
  HttpSuccess(HttpEvent httpEvent) : super(httpEvent);

  @override
  List<Object> get props => [];
}

///请求成功且有数据
class HttpSuccessWithData<T> extends HttpSuccess {
  final T data;

  HttpSuccessWithData(HttpEvent httpEvent, this.data) : super(httpEvent);
}
